home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 102_01.zip / BG.C < prev    next >
Text File  |  1993-06-03  |  19KB  |  786 lines

  1. /*
  2.     Backgammon...finally, some"one" else to play against than just
  3.     my girlfriend, who hates to lose! (but then, so do I...and this
  4.     program doesn't do too bad a job at keeping me honest)
  5.  
  6.     Modified for BDS C by Leor Zolman, 2/82
  7. */
  8.  
  9. #include <bdscio.h>
  10.  
  11. #define H19 1        /* true if to be run on H19 terminal */
  12. #define NIL (-1)
  13. #define MAXGMOV 10
  14. #define MAXIMOVES 1000
  15.  
  16. char level;        /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
  17. int die1;
  18. int die2;
  19. int i;
  20. int j;
  21. int l;
  22. int m;
  23. int count;
  24.  
  25. int red[31];
  26. int white[31];
  27. int probability[13];
  28.  
  29. int imoves;
  30. int goodmoves[MAXGMOV];
  31. int probmoves[MAXGMOV];
  32.  
  33. struct {
  34.     int pos[4];
  35.     int mov[4];
  36. } moves[MAXIMOVES];
  37.  
  38.  
  39. exinit()
  40. {
  41.     int i;
  42.     setmem(externs(), endext() - externs(), 0);
  43.     red[1] = white[1] = 2;
  44.     red[12] = white[12] = 5;
  45.     red[17] = white[17] = 3;
  46.     red[19] = white[19] = 5;
  47.     probability[0] = 0;
  48.     probability[1] = 11;
  49.     probability[2] = 12;
  50.     probability[3] = 13;
  51.     probability[4] = 14;
  52.     probability[5] = 15;
  53.     probability[6] = 16;
  54.     probability[7] = 6;
  55.     probability[8] = 5;
  56.     probability[9] = 4;
  57.     probability[10] = 3;
  58.     probability[11] = 2;
  59.     probability[12] = 1;
  60. }
  61.  
  62. main()
  63. {
  64.     int t,k,n,go[5];
  65.     char c, s[MAXLINE];
  66.     int i;
  67.     int first;    /* true on first move only */
  68.     int mywins, hiswins;
  69.  
  70.     printf("\n\nWelcome to BACKGAMMON!\n");
  71.  
  72.     nrand (0,"Do you need instructions? ");
  73.     if(tolower(getchar())=='y')
  74.         instructions();
  75.     else puts("\n\n");
  76.  
  77.     mywins = hiswins = 0;
  78.  
  79.     printf( "Choose the level of your oppponent:\n");
  80.     printf( "Type 'b' for beginner, or 'i' for intermediate,\n");
  81.     printf( "or anything else to play an expert... ?");
  82.     level='e';
  83.     if((c = tolower(getchar()))=='b') level='b';
  84.     else if(c=='i') level='i';
  85.  
  86.     printf( "\n\nI'll play white, and you'll play red.\n\n");
  87.  
  88. newgame:
  89.     exinit();
  90.     first = 1;
  91.     go[5]=NIL;
  92.  
  93.     printf("Let's throw the dice to see who goes first:\n");
  94.  
  95. throw:    roll();
  96.     printf("I throw: ");
  97.     sleep(15);
  98.     printf("%d, and you throw: ",die1);
  99.     sleep(15);
  100.     printf("%d ... ",die2);
  101.     sleep(15);
  102.     if (die1 == die2) {
  103.         printf("Tied up, so let's try again:\n");
  104.         goto throw;
  105.     }
  106.     printf("%s go first...\n\n", die1 > die2 ? "I" : "You");
  107.     if (die2 > die1) goto nowhmove;
  108.     
  109. whitesmv:
  110.     if (!first) roll();    /* skip roll on first move */
  111.     order();
  112.     first = 0;        /* after this, not first roll anymore */
  113. #if H19
  114.     printf( "\nWhite rolls \33p %d,%d \33q... ",die1,die2);
  115. #else
  116.     printf( "\nWhite rolls %d,%d ... ",die1,die2);
  117. #endif
  118.     if (!chkmov(white,red)) {
  119.         printf("White has no moves. Foo.\n");
  120.         goto nowhmove;
  121.     }
  122.     printf( "White's move is: ");
  123.     if(nextmove(white,red)==NIL)goto nowhmove;
  124.     if(piececount(white,0,24)==0) {
  125.       printf( "\7White wins!\n");
  126.       printf("\nGame score:   Me: %d,  You: %d\n",++mywins,hiswins);
  127.       if (mywins == hiswins)
  128.         printf("All tied up! Who's gonna pull ahead?\n");
  129.       else if (mywins > 2 && !hiswins)
  130.         printf ("It's about time you managed to win a game!\n");
  131.       else switch(nrand(1) % 5) {
  132.         case 4:
  133.         case 0:    printf("Aren't you ashamed? You've been beaten ");
  134.             printf("by a computer...\n");
  135.             break;
  136.         case 1:    printf("Not bad for a dumb program, eh?\n");
  137.             break;
  138.         case 2:    printf("Better luck next time, sucker....\n");
  139.             break;
  140.         case 3:    printf("Maybe you'd better stick to checkers?\n");
  141.             break;
  142.       }
  143.       goto again;
  144.     }
  145.  
  146. nowhmove:
  147.     prtbrd();
  148.     if (!first) roll();        /* skip roll on first move */
  149.     first = 0;            /* after this, not 1st roll anymore */
  150.  
  151. retry:
  152.     order();
  153.  
  154. #if H19
  155.     printf( "Your roll is \33p %d, %d \33q ... ",die1,die2);
  156. #else
  157.     printf( "Your roll is %d,%d ... ",die1,die2);
  158. #endif
  159.     if (!chkmov(red,white)) {
  160.         printf("Sorry, you have no possible moves.\n");
  161.         printf("Type any key to let me make my next move: ");
  162.         getchar();
  163.         goto whitesmv;
  164.     }
  165.  
  166.     printf("your move? ");
  167.     while (!kbhit()) nrand(1);   /* Exercize the random generator while */
  168.     gets(s);             /* waiting for a move to be made...    */
  169.  
  170.     if (ignore_sp(s) == '?' || ignore_sp(s) == 'h') {
  171.       puts("\nType either a list of moves, separated by spaces, or:\n");
  172.       puts("    q -- to quit the current game\n");
  173.       puts("    b -- to see the board\n");
  174.       puts("    ? -- to see these options (h does the same thing)\n");
  175.       puts("Do you want to see the long instructions? ");
  176.       if (tolower(getchar()) == 'y') instructions();
  177.       puts("\n");
  178.       goto retry;
  179.     }
  180.  
  181.     if (ignore_sp(s) == 'q') {    /* check for quit command */
  182.         puts("Are you sure you want to quit? ");
  183.         if (tolower(getchar()) == 'y') goto again;
  184.         putchar('\n');
  185.         goto retry;
  186.     }
  187.  
  188.     if (ignore_sp(s) == 'b') {    /* check for print board command */
  189.         prtbrd();
  190.         goto retry;
  191.     }
  192.                     /* check for null move */
  193.     if( ignore_sp(s) != '-' && !isdigit(ignore_sp(s))) {
  194.         printf("You MUST make a move!\n");
  195.         goto retry;
  196.     }
  197.  
  198.     for (i = 0; s[i]; i++)        /* convert commas to spaces */
  199.      if (s[i] == ',') s[i] = ' ';
  200.  
  201.     n=sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
  202.  
  203.     if( (die1 != die2 && n > 2) || n > 4) {
  204.         printf( "You've made too many moves;\n");
  205.         goto retry;
  206.     }
  207.  
  208.     if( ((die1 != die2) && n < 2) || ((die1 == die2) && n < 4)) {
  209.         if (n == cntred()) goto moveok;
  210.         printf("Are you sure you can't make all the moves? ");
  211.         if (tolower(getchar()) != 'y') {
  212.         printf("\nOK, then let's try it again:\n");
  213.         goto retry;
  214.         }
  215.         putchar('\n');
  216.     }
  217.  
  218. moveok:    go[n]=NIL;
  219.     if(*s=='-'){
  220.         go[0]= -go[0];
  221.         t=die1;
  222.         die1=die2;
  223.         die2=t;
  224.     }
  225.     for(k=0; k<n; k++) {
  226.         if(0<=go[k] && go[k]<=24)continue;
  227.         else{
  228.         printf( "Sorry, move %d is illegal.\n",go[k]);
  229.         goto retry;
  230.         }
  231.     }
  232.     if(play(red,white,go))goto retry;
  233.     if(piececount(red,0,24)==0){
  234.         printf( "\n\7Red wins.\n");
  235.         printf("\nGame score:   Me: %d,  You: %d\n",mywins,++hiswins);
  236.         if (mywins == hiswins)
  237.         printf("Looks like now we're dead even...tiebreaker time!\n");
  238.         else if (hiswins > 2 && !mywins)
  239.         printf("See? I'm not THAT stupid after all!\n");
  240.         else switch(nrand(1) % 5) {
  241.         case 0:    printf( "Congratulations! You've just defeated a ");
  242.             printf( "dumb machine.\n");
  243.             break;
  244.         case 1:    printf("Sigh...at least I put up a good fight, eh?\n");
  245.             break;
  246.         case 2: printf("Darn....I'll get you next time, human!\n");
  247.             break;
  248.         case 3:    printf("Mumble...those unlucky rolls will do it ");
  249.             printf("every time!\n");
  250.             break;
  251.         case 4:    printf("Not bad... for a dumb human!\n");
  252.         }
  253.   again:    printf("\nWould you like to play another game? ");
  254.         if (tolower(getchar()) != 'y') exit();
  255.         printf("\n\n");
  256.         goto newgame;
  257.     }
  258.     goto whitesmv;
  259. }
  260.  
  261. char ignore_sp(s)    /* return first non-whitespace char at s: */
  262. char *s;
  263. {
  264.     char c;
  265.     while (isspace(c = *s++));
  266.     return tolower(c);
  267. }
  268.  
  269. play(player,playee,pos)
  270. int *player,*playee,pos[];
  271. {
  272.     int k,n,die,ipos;
  273.     for(k=0;k<player[0];k++){  /*blots on player[0] must be moved first*/
  274.         if(pos[k]==NIL)break;
  275.         if(pos[k]!=0){
  276.         printf( "\nPiece on BAR (position 0) must be moved first\n");
  277.         return(-1);
  278.         }
  279.     }
  280.     for(k=0;(ipos=pos[k])!=NIL;k++){
  281.         die=k?die2:die1;
  282.         n=25-ipos-die;
  283.         if(player[ipos]==0)goto badmove;
  284.         if(n>0 && playee[n]>=2)goto badmove;
  285.         if(n<=0){
  286.         if(piececount(player,0,18)!=0)goto badmove;
  287.         if((ipos+die)!=25 &&
  288.             piececount(player,19,24-die)!=0)goto badmove;
  289.         }
  290.         player[ipos]--;
  291.         player[ipos+die]++;
  292.     }
  293.     for(k=0;pos[k]!=NIL;k++){
  294.         die=k?die2:die1;
  295.         n=25-pos[k]-die;
  296.         if(n>0 && playee[n]==1){
  297.         playee[n]=0;
  298.         playee[0]++;
  299.         }
  300.     }
  301.     return(0);
  302.  
  303. badmove:
  304.     printf( "Move %d is not legal. Enter all moves again:\n",ipos);
  305.     while(k--){
  306.         die=k?die2:die1;
  307.         player[pos[k]]++;
  308.         player[pos[k]+die]--;
  309.     }
  310.     prtbrd();
  311.     return(-1);
  312. }
  313.  
  314. cntred()            /* count up number of red's pieces */
  315. {
  316.     int i, count;
  317.     for (count = 0, i = 0; i < 25; i++) count += red[i];
  318.     return count;
  319. }
  320.  
  321. chkmov(player,playee)        /* return true if player has possible move */
  322. int *player, *playee;
  323. {
  324.     int k;
  325.     imoves=0;
  326.     movegen(player,playee);
  327.     if(die1!=die2) {
  328.         k = die1;     die1 = die2;    die2 = k;
  329.         movegen(player,playee);
  330.         k = die1;    die1 = die2;    die2 = k;
  331.     }
  332.     return imoves;
  333. }
  334.  
  335. nextmove(player,playee)
  336. int *player,*playee;
  337. {
  338.     int k;
  339.     if(die1!=die2){
  340.     k=die1;  die1=die2;  die2=k;
  341.     }
  342.     k=strategy(player,playee);        /*select kth possible move*/
  343.     prtmov(k);
  344.     update(player,playee,k);
  345.     return(0);
  346. }
  347.  
  348. prtmov(k)
  349. int k;
  350. {
  351.     int commaf;
  352.     int n;
  353.     int i;
  354.     commaf = 0;
  355.     if(k==NIL)printf( " No move possible\n");
  356.     else for(n=0;n<4;n++) {
  357.         if(moves[k].pos[n]==NIL)break;
  358.         if (commaf) putchar(',');
  359.         i = 25-moves[k].pos[n];
  360.         if (i == 0 || i == 25)
  361.         printf( " BAR (%d)",moves[k].mov[n]);
  362.         else
  363.         printf( " %d (%d)",i,moves[k].mov[n]);
  364.         commaf = 1;
  365.     }
  366.     putchar('\n');
  367. }
  368.  
  369. update(player,playee,k)
  370. int *player,*playee,k;
  371. {
  372.     int n,t;
  373.     for(n=0;n<4;n++){
  374.         if(moves[k].pos[n]==NIL)break;
  375.         player[moves[k].pos[n]]--;
  376.         player[moves[k].pos[n]+moves[k].mov[n]]++;
  377.         t=25-moves[k].pos[n]-moves[k].mov[n];
  378.         if(t>0 && playee[t]==1){
  379.         playee[0]++;
  380.         playee[t]--;
  381.         }
  382.     }
  383. }
  384.  
  385. piececount(player,startrow,endrow)
  386. int *player,startrow,endrow;
  387. {
  388.     int sum;
  389.     sum=0;
  390.     while(startrow<=endrow)
  391.     sum+=player[startrow++];
  392.     return(sum);
  393. }
  394.  
  395. roll()
  396. {
  397.     int temp;
  398.     die1=(nrand(1)>>8)%6+1;
  399.     die2=(nrand(1)>>8)%6+1;
  400. }
  401.  
  402. order()            /* place the two dice in descending order */
  403. {
  404.     int temp;
  405.     if (die1 < die2) {        /* first die always bigger */
  406.         temp = die1;
  407.         die1 = die2;
  408.         die2 = temp;
  409.     }
  410. }
  411.  
  412.  
  413. movegen(mover,movee)
  414. int *mover,*movee;
  415. {
  416.     int k;
  417.     for(i=0;i<=24;i++){
  418.         count=0;
  419.         if(mover[i]==0)continue;
  420.         if((k=25-i-die1)>0 && movee[k]>=2)
  421.             if(mover[0]>0)break;
  422.             else continue;
  423.         if(k<=0){
  424.             if(piececount(mover,0,18)!=0)break;
  425.             if((i+die1)!=25 &&
  426.                 piececount(mover,19,24-die1)!=0)break;
  427.         }
  428.         mover[i]--;
  429.         mover[i+die1]++;
  430.         count=1;
  431.         for(j=0;j<=24;j++){
  432.             if(mover[j]==0)continue;
  433.             if((k=25-j-die2)>0 && movee[k]>=2)
  434.                 if(mover[0]>0)break;
  435.                 else continue;
  436.             if(k<=0){
  437.                 if(piececount(mover,0,18)!=0)break;
  438.                 if((j+die2)!=25 &&
  439.                     piececount(mover,19,24-die2)!=0)break;
  440.             }
  441.             mover[j]--;
  442.             mover[j+die2]++;
  443.             count=2;
  444.             if(die1!=die2){
  445.                 moverecord(mover);
  446.                 if(mover[0]>0)break;
  447.                 else continue;
  448.             }
  449.             for(l=0;l<=24;l++){
  450.                 if(mover[l]==0)continue;
  451.                 if((k=25-l-die1)>0 && movee[k]>=2)
  452.                 if(mover[0]>0)break;
  453.                 else continue;
  454.                 if(k<=0){
  455.                 if(piececount(mover,0,18)!=0)break;
  456.                 if((l+die2)!=25 &&
  457.                     piececount(mover,19,24-die1)!=0)break;
  458.                 }
  459.                 mover[l]--;
  460.                 mover[l+die1]++;
  461.                 count=3;
  462.                 for(m=0;m<=24;m++){
  463.                 if(mover[m]==0)continue;
  464.                 if((k=25-m-die1)>=0 && movee[k]>=2)
  465.                     if(mover[0]>0)break;
  466.                     else continue;
  467.                 if(k<=0){
  468.                     if(piececount(mover,0,18)!=0)break;
  469.                     if( (m+die2) != 25 &&
  470.                         piececount(mover,19,24-die1)!=0)break;
  471.                 }
  472.                 count=4;
  473.                 moverecord(mover);
  474.                 if(mover[0]>0)break;
  475.                 }
  476.                 if(count==3)moverecord(mover);
  477.                 else{
  478.                 mover[l]++;
  479.                 mover[l+die1]--;
  480.                 }
  481.                 if(mover[0]>0)break;
  482.             }
  483.             if(count==2)moverecord(mover);
  484.             else{
  485.                 mover[j]++;
  486.                 mover[j+die1]--;
  487.             }
  488.             if(mover[0]>0)break;
  489.         }
  490.         if(count==1)moverecord(mover);
  491.         else{
  492.             mover[i]++;
  493.             mover[i+die1]--;
  494.         }
  495.         if(mover[0]>0)break;
  496.     }
  497. }
  498.  
  499. moverecord(mover)
  500. int *mover;
  501. {
  502.     int t;
  503.     if(imoves>=MAXIMOVES)goto undo;;
  504.     for(t=0;t<=3;t++)
  505.         moves[imoves].pos[t]= NIL;
  506.     switch(count){
  507. case 4:
  508.         moves[imoves].pos[3]=m;
  509.         moves[imoves].mov[3]=die1;
  510. case 3:
  511.         moves[imoves].pos[2]=l;
  512.         moves[imoves].mov[2]=die1;
  513. case 2:
  514.         moves[imoves].pos[1]=j;
  515.         moves[imoves].mov[1]=die2;
  516. case 1:
  517.         moves[imoves].pos[0]=i;
  518.         moves[imoves].mov[0]=die1;
  519.         imoves++;
  520.     }
  521. undo:
  522.     switch(count){
  523. case 4:
  524.         break;
  525. case 3:
  526.         mover[l]++;
  527.         mover[l+die1]--;
  528.         break;
  529. case 2:
  530.         mover[j]++;
  531.         mover[j+die2]--;
  532.         break;
  533. case 1:
  534.         mover[i]++;
  535.         mover[i+die1]--;
  536.     }
  537. }
  538.  
  539.  
  540. strategy(player,playee)
  541. int *player,*playee;
  542. {
  543.     int k,n,nn,bestval,moveval,prob;
  544.     n=0;
  545.     if(imoves==0)return(NIL);
  546.     goodmoves[0]=NIL;
  547.     bestval= -32000;
  548.     for(k=0;k<imoves;k++){
  549.         if((moveval=eval(player,playee,k,&prob))<bestval)continue;
  550.         if(moveval>bestval){
  551.         bestval=moveval;
  552.         n=0;
  553.         }
  554.         if(n<MAXGMOV){
  555.         goodmoves[n]=k;
  556.         probmoves[n++]=prob;
  557.         }
  558.     }
  559.     if(level=='e' && n>1){
  560.         nn=n;
  561.         n=0;
  562.         prob=32000;
  563.         for(k=0;k<nn;k++){
  564.         if((moveval=probmoves[k])>prob)continue;
  565.         if(moveval<prob){
  566.             prob=moveval;
  567.             n=0;
  568.         }
  569.         goodmoves[n]=goodmoves[k];
  570.         probmoves[n++]=probmoves[k];
  571.         }
  572.     }
  573.     return(goodmoves[(nrand(1)>>4)%n]);
  574. }
  575.  
  576. eval(player,playee,k,prob)
  577. int *player,*playee,k,*prob;
  578. {
  579.     int newtry[31],newother[31],*r,*q,*p,n,sum,first;
  580.     int ii,lastwhite,lastred;
  581.     *prob=sum=0;
  582.     r=player+25;
  583.     p=newtry;
  584.     q=newother;
  585.     while(player<r){
  586.         *p++= *player++;
  587.         *q++= *playee++;
  588.     }
  589.     q=newtry+31;
  590.     for(p=newtry+25;p<q;) *p++ = 0;    /*zero out spaces for hit pieces*/
  591.     for(n=0;n<4;n++){
  592.         if(moves[k].pos[n]==NIL)break;
  593.         newtry[moves[k].pos[n]]--;
  594.         newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
  595.         if(ii<25 && newother[25-ii]==1){
  596.         newother[25-ii]=0;
  597.         newother[0]++;
  598.         if(ii<=15 && level=='e')sum++;    /*hit if near other's home*/
  599.         }
  600.     }
  601.     for(lastred=0;newother[lastred]==0;lastred++);
  602.     for(lastwhite=0;newtry[lastwhite]==0;lastwhite++);
  603.     lastwhite=25-lastwhite;
  604.     if(lastwhite<=6 && lastwhite<lastred)sum=1000;
  605.     if(lastwhite<lastred && level=='e'
  606.         && lastwhite>6){            /*expert's running game.
  607.                           First priority to get all
  608.                           pieces into white's home*/
  609.         for(sum=1000;lastwhite>6;lastwhite--)
  610.         sum=sum-lastwhite*newtry[25-lastwhite];
  611.     }
  612.     for(first=0;first<25;first++)
  613.         if(newother[first]!=0)break;    /*find other's first piece*/
  614.     q=newtry+25;
  615.     for(p=newtry+1;p<q;)if(*p++ > 1)sum++;    /*blocked points are good*/
  616.     if(first>5){    /*only stress removing pieces if homeboard
  617.               cannot be hit
  618.             */
  619.         q=newtry+31;
  620.         p=newtry+25;
  621.         for(n=6;p<q;n--)
  622.         sum += *p++ * n;    /*remove pieces, but just barely*/
  623.     }
  624.     if(level!='b'){
  625.         r=newtry+25-first;    /*singles past this point can't be hit*/
  626.         for(p=newtry+7;p<r;)
  627.         if(*p++ == 1)sum--;    /*singles are bad after 1st 6 points
  628.                       if they can be hit*/
  629.         q=newtry+3;
  630.         for(p=newtry;p<q;)sum-= *p++;  /*bad to be on 1st three points*/
  631.     }
  632.  
  633.     for(n=1;n<=4;n++)
  634.         *prob += n*getprob(newtry,newother,6*n-5,6*n);
  635.     return(sum);
  636. }
  637.  
  638. instructions()
  639. {
  640.     printf( "\n\n");
  641.     printf( "To play backgammon, type the numbers of the points\n");
  642.     printf( "from which pieces are to be moved. Thus, if the\n");
  643.     printf( "roll is '3,5', typing '2 6' will move a piece\n");
  644.     printf( "from point 2 three spaces to point 5,\n");
  645.     printf( "and a piece from point 6 forward to\n");
  646.     printf( "point 11.  If the moves must be made in the\n");
  647.     printf( "opposite order, the first character typed must\n");
  648.     printf( "be a minus ('-'). Thus, typing\n");
  649.     printf( "'-2 6' moves the piece on point 2\n");
  650.     printf( "by 5, and the piece on point 6 by 3.\n");
  651.     printf( "If you want to move a single piece several times,\n");
  652.     printf( "the sequence of points from which it is to be\n");
  653.     printf( "moved must be typed. Thus '14 17' will move\n");
  654.     printf( "a piece from point 14 to point 17 and thence to\n");
  655.     printf( "to point 22.\n");
  656.     printf( "Instead of entering a move, you can instead type:\n");
  657.     printf( "    q    to quit the game, or\n");
  658.     printf( "    b    to print the board again.\n\n");
  659.  
  660.     printf( "\nType any key to continue instructions: "); getchar();
  661.  
  662.     printf( "\nIf a double is rolled, you should type four numbers.\n");
  663.     printf( "Red pieces that have been removed from the board by\n");
  664.     printf( "being hit by white are on point 0 and\n");
  665.     printf( "must be brought in before any other move can be made.\n");
  666.     printf( "White pieces that are hit are removed to point 25.\n");
  667.     printf( "You will not be allowed to make an illegal move, or\n");
  668.     printf( "to make too many moves. However, if you make too\n");
  669.     printf( "few moves, the program does not care. In particular\n");
  670.     printf( "you may skip your turn by typing a 'new-line'\n");
  671.     printf( "all by itself.\n\n");
  672. }
  673.  
  674. getprob(player,playee,start,finish)
  675. int *player,*playee,start,finish;
  676. {            /*returns the probability (times 102) that any
  677.               pieces belonging to 'player' and lying between
  678.               his points 'start' and 'finish' will be hit
  679.               by a piece belonging to playee
  680.             */
  681.     int k,n,sum;
  682.     sum=0;
  683.     for(;start<=finish;start++){
  684.         if(player[start]==1){
  685.         for(k=1;k<=12;k++){
  686.             if((n=25-start-k)<0)break;
  687.             if(playee[n]!=0)sum += probability[k];
  688.         }
  689.         }
  690.     }
  691.     return(sum);
  692. }
  693.  
  694. prtbrd()
  695. {
  696.     int k;
  697.     printf( "\nWhite's Home (mine)\n");        /* first line */
  698.  
  699.     for(k=1;k<=6;k++)                /* top label line */
  700.         printf( "%4d",k);
  701.     printf( "    ");
  702.     for(k=7;k<=12;k++)printf( "%4d",k);
  703.     putchar('\n' );
  704.  
  705.     for(k=1;k<=54;k++)putchar('_' );        /* delimiter line */
  706.     putchar('\n' );
  707.  
  708.     numline(red,white,1,6);                /* numbers line */
  709.     printf( "    ");
  710.     numline(red,white,7,12);
  711.     putchar('\n' );
  712.  
  713.     colorline(red,'R',white,'W',1,6);        /* letters line */
  714.     printf( "    ");
  715.     colorline(red,'R',white,'W',7,12);
  716.     putchar('\n' );
  717.  
  718.     if(white[0]!=0)printf( "%28dW\n",white[0]);    /* white's bar */
  719.     else putchar('\n' );
  720.  
  721.     if(red[0]!=0)printf( "%28dR\n",red[0]);        /* red's bar */
  722.     else putchar('\n' );
  723.  
  724.     colorline(white,'W',red,'R',1,6);        /* letters line */
  725.     printf( "    ");
  726.     colorline(white,'W',red,'R',7,12);
  727.     putchar('\n' );
  728.  
  729.     numline(white,red,1,6);                /* numbers line */
  730.     printf( "    ");
  731.     numline(white,red,7,12);
  732.     putchar('\n' );
  733.  
  734.     for(k=1;k<=54;k++)putchar('_' );        /* delimiter line */
  735.     putchar('\n' );
  736.  
  737.     for(k=24;k>=19;k--)printf( "%4d",k);        /* bottom label line */
  738.     printf( "    ");
  739.     for(k=18;k>=13;k--)printf( "%4d",k);
  740.  
  741.     printf( "\nRed's Home (yours)\n\n");        /* last line */
  742. }
  743.  
  744. numline(upcol,downcol,start,fin)
  745. int *upcol,*downcol,start,fin;
  746. {
  747.     int k,n;
  748.     for(k=start;k<=fin;k++){
  749.         if((n=upcol[k])!=0 || (n=downcol[25-k])!=0)
  750.  
  751. #if H19
  752.         if ((upcol[k] && upcol == red) ||
  753.             (downcol[25-k] && downcol == red))
  754.             if (n < 10)
  755.                 printf("   \33p%1d\33q",n);
  756.             else
  757.                 printf("  \33p%2d\33q",n);
  758.         else
  759.             printf("%4d",n);
  760. #else
  761.         printf("%4d",n);
  762. #endif
  763.  
  764.         else printf( "    ");
  765.     }
  766. }
  767.  
  768. colorline(upcol,c1,downcol,c2,start,fin)
  769. int *upcol,*downcol,start,fin;
  770. char c1,c2;
  771. {
  772.     int k;
  773.     char c;
  774.     for(k=start;k<=fin;k++){
  775.         c=' ';
  776.         if(upcol[k]!=0)c=c1;
  777.         if(downcol[25-k]!=0)c=c2;
  778. #if H19
  779.     if (c == 'R')
  780.         printf("   \33p%c\33q",c);    /* make 'R' reverse video */
  781.     else
  782. #endif
  783.          printf("   %c",c);
  784.     }
  785. }
  786.